"""Data models for the CLU API service."""

import uuid
from typing import Optional, List, Any, Dict
from pydantic import BaseModel, Field
from datetime import datetime, timezone, timedelta

# Type aliases and constants
namespace = uuid.NAMESPACE_DNS
# 东八区时区常量
CHINA_TZ = timezone(timedelta(hours=8))

class ProjectResponse(BaseModel):
    """Response model for project information."""
    id: uuid.UUID
    name: str
    description: Optional[str]
    culture: str
    usageScenario: str = ""
    domain: str = ""
    versionsCount: int = 1
    createdDateTime: datetime
    endpoints: Dict[str, Any] = {}
    endpointHitsCount: int = 0
    activeVersion: str = "0.1"
    ownerEmail: Optional[str] = None
    tokenizerVersion: str = "1.0.0"
    # 新增字段：最新部署信息
    latestDeploymentName: Optional[str] = None
    latestDeploymentTrainingTime: Optional[str] = None  # 格式化为 YYYY-MM-DD HH:MM:SS

    @classmethod
    def _convert_to_china_time(cls, time_value) -> Optional[datetime]:
        """将时间值转换为东八区时间。"""
        if not time_value:
            return None
        
        china_tz = CHINA_TZ
        
        if isinstance(time_value, str):
            try:
                dt = datetime.fromisoformat(time_value.replace('Z', '+00:00'))
                return dt.astimezone(china_tz)
            except:
                return None
        elif isinstance(time_value, datetime):
            if time_value.tzinfo is None:
                # 如果没有时区信息，假设为UTC
                time_value = time_value.replace(tzinfo=timezone.utc)
            return time_value.astimezone(china_tz)
        
        return None
    
    @classmethod
    def from_api_response(cls, item: Dict[str, Any], latest_deployment_name: Optional[str] = None, 
                         latest_deployment_training_time: Optional[str] = None) -> "ProjectResponse":
        """Create ProjectResponse from API response."""
        return cls(
            id=uuid.uuid3(namespace, item.get('projectName')),
            name=item.get('projectName'),
            description=item.get('description'),
            culture=item.get('language'),
            createdDateTime=cls._convert_to_china_time(item.get('createdDateTime')), #TODO: 可能是UTC时间，未验证
            latestDeploymentName=latest_deployment_name,
            latestDeploymentTrainingTime=latest_deployment_training_time
        )

class TrainingConfig(BaseModel):
    """Configuration for model training."""
    modelLabel: str
    trainingMode: str = "advanced"
    evaluationOptions: Dict[str, str] = {"kind": "manual"}
    trainingConfigVersion: str = "latest"

class DeploymentConfig(BaseModel):
    """Configuration for model deployment."""
    trainedModelLabel: str


class IntentResponse(BaseModel):
    """Response model for intent information."""
    id: str  # 使用UUID5生成的固定ID
    category: str
    createdDateTime: Optional[datetime] = None
    lastModifiedDateTime: Optional[datetime] = None

    class Config:
        from_attributes = True

    @classmethod
    def from_intent_data(cls, intent_data: Dict[str, Any]) -> "IntentResponse":
        """
        从导出的Intent数据创建IntentResponse。
        
        Args:
            intent_data: 导出的Intent数据字典
            
        Returns:
            IntentResponse实例
        """
        # 提取Intent名称
        intent_name = None
        for name_field in ["name", "intent", "intentName", "category"]:
            if name_field in intent_data:
                intent_name = intent_data[name_field]
                break
        
        if not intent_name:
            raise ValueError(f"无法从 Intent 数据中提取名称: {intent_data}")
        
        # 使用UUID5生成固定ID
        intent_id = str(uuid.uuid5(uuid.NAMESPACE_DNS, intent_name))
        
        # 提取时间字段（如果存在）
        created_time = intent_data.get("createdDateTime")
        modified_time = intent_data.get("lastModifiedDateTime")
        
        # 处理时间字符串转换，转换为东八区时间
        china_tz = CHINA_TZ
        
        if isinstance(created_time, str):
            try:
                dt = datetime.fromisoformat(created_time.replace('Z', '+00:00'))
                created_time = dt.astimezone(china_tz)
            except:
                created_time = None
        
        if isinstance(modified_time, str):
            try:
                dt = datetime.fromisoformat(modified_time.replace('Z', '+00:00'))
                modified_time = dt.astimezone(china_tz)
            except:
                modified_time = None
        
        return cls(
            id=intent_id,
            category=intent_name,
            createdDateTime=created_time,
            lastModifiedDateTime=modified_time
        )


class ConversationRequest(BaseModel):
    """Request model for conversation analysis."""
    message: str
    projectName: str
    deploymentName: str
    language: str = "zh"
    id: str = "1"
    participantId: str = "1"
    verbose: bool = False  # 控制是否返回详细信息
    top_intents: Optional[int] = 5  # 限制返回的Intent数量

class ExportResultRequest(BaseModel):
    """Request model for getting export result."""
    result_url: str


class ProjectDeploymentPair(BaseModel):
    """Model for project and deployment pair."""
    projectName: str
    deploymentName: str


class BatchConversationRequest(BaseModel):
    """Request model for batch conversation analysis."""
    message: str
    targets: List[ProjectDeploymentPair]
    language: str = "zh"
    id: str = "1"
    participantId: str = "1"
    verbose: bool = False  # 控制是否返回详细信息
    top_intents: Optional[int] = 5  # 限制返回的Intent数量


class DefaultConversationRequest(BaseModel):
    """默认目标会话分析请求模型（不包含targets字段）。"""
    message: str
    language: str = "zh"
    id: str = "1"
    participantId: str = "1"
    verbose: bool = False  # 控制是否返回详细信息
    top_intents: Optional[int] = 5  # 限制返回的Intent数量


class BatchConversationResponse(BaseModel):
    """Response model for batch conversation analysis."""
    message: str
    results: List[Dict[str, Any]]
    success_count: int
    error_count: int
    hintIntent: Optional[str] = None  # 最终命中的意图名称
    sourceProject: Optional[str] = None  # 意图来源的项目名称
    sourceDeployment: Optional[str] = None  # 意图来源的部署名称
    confidenceScore: Optional[float] = None  # 意图的置信度分数
    entities: Optional[List[Dict[str, Any]]] = None  # 实体信息（如果存在）


class UtilsBase(BaseModel):
    """
    工具类基础模型。
    
    预留用于各种工具类数据结构的扩展，保持架构的可扩展性。
    当前为空实现，后续可根据具体需求添加通用字段。
    """
    pass


class CosmosDBQueryRequest(BaseModel):
    """CosmosDB查询请求模型。"""
    target_key: str = Field(default="System.LUIS.ThresholdScore", description="要查询的配置键名")


class CosmosDBQueryResponse(BaseModel):
    """CosmosDB查询响应模型。"""
    key: str
    value: Optional[Any] = None
    found: bool
    query_time: datetime


class IntentQueryRequest(BaseModel):
    """意图查询请求模型，支持分页参数。"""
    asset_kind: str = Field(default="intents", description="资产类型，默认为intents")
    skip: Optional[int] = Field(default=0, ge=0, description="跳过的记录数，用于分页")
    take: Optional[int] = Field(default=None, ge=1, le=1000, description="获取的记录数，用于分页，最大1000")


class IntentQueryResponse(BaseModel):
    """意图查询响应模型，包含分页信息。"""
    intents: List[Dict[str, Any]]
    total_count: int
    skip: int
    take: Optional[int]
    has_more: bool
    project_name: Optional[str] = None


class CheckedApplicationsRequest(BaseModel):
    """已检查应用程序查询请求模型。"""
    checked: Optional[bool] = Field(default=True, description="筛选条件：True-仅返回checked为True的应用，False-仅返回checked为False的应用，None-不筛选")


class CheckedApplicationsResponse(BaseModel):
    """已检查应用程序查询响应模型。"""
    application_names: List[str]
    total_count: int
    filtered_count: int
    checked_filter: Optional[bool]
    query_time: datetime
